package com.hope.bubble.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hope.bubble.common.exception.ApiAsserts;
import com.hope.bubble.jwt.JwtUtil;
import com.hope.bubble.mapper.BubbleFollowMapper;
import com.hope.bubble.mapper.BubbleTopicMapper;
import com.hope.bubble.mapper.UmsUserMapper;
import com.hope.bubble.model.dto.LoginDTO;
import com.hope.bubble.model.dto.RegisterDTO;
import com.hope.bubble.model.entity.BubbleFollow;
import com.hope.bubble.model.entity.BubblePost;
import com.hope.bubble.model.entity.UmsUser;
import com.hope.bubble.model.vo.ProfileVO;
import com.hope.bubble.service.IUmsUserService;
import com.hope.bubble.utils.MD5Utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.Date;

/**
 * 文件名：IUmsUserServiceImpl
 * 创建者：hope
 * 邮箱：1602774287@qq.com
 * 微信：hope4cc
 * 创建时间：2022/10/21-20:21
 * 描述： 用户 注册 信息 登录
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class IUmsUserServiceImpl
        extends ServiceImpl<UmsUserMapper, UmsUser> implements IUmsUserService {

    @Autowired
    private BubbleTopicMapper bubbleTopicMapper;

    @Autowired
    private BubbleFollowMapper bubbleFollowMapper;

    @Override
    public UmsUser executeRegister(RegisterDTO dto) {
        //查询是否有相同用户名的用户
        //初始化mybatis-plus 提供的 LambdaQueryWrapper 查询包装类
        LambdaQueryWrapper<UmsUser> wrapper = new LambdaQueryWrapper<>();
        // 判断数据库和前端传过来的用户名是否相等,或者 数据库邮箱和前端传回来的邮箱是否相等
        wrapper.eq(UmsUser::getUsername, dto.getName()).or().eq(UmsUser::getEmail, dto.getEmail());
        //mybatis-plus 提供 selectOne 查询一条数据
        UmsUser umsUser = baseMapper.selectOne(wrapper);
        //判断是 数据库是否存在 !取反  不为空的情况加 说明账号或者邮箱在数据库中已存在
        if (!ObjectUtils.isEmpty(umsUser)) {
            ApiAsserts.fail("账号或邮箱已存在！");
        }
        //否则就创建 将前端传回来的 赋值给实体类 初始化其余字段 保存到数据库 md5加密(密码)
//        UmsUser.builder() 链式编程
        UmsUser addUser = UmsUser.builder()
                .username(dto.getName())
                .alias(dto.getName())
                .password(MD5Utils.getPwd(dto.getPass()))
                .email(dto.getEmail())
                .createTime(new Date())
                .status(true)
                .build();
        //调用mapper 插入数据
        baseMapper.insert(addUser);
        //返回控制层
        return addUser;
    }



    @Override
    public UmsUser getUserByUsername(String username) {
        //调用mapper接口 查询一条数据 eq 条件 就是 数据库用户名与dto的用户名
        return baseMapper.selectOne(new LambdaQueryWrapper<UmsUser>().eq(UmsUser::getUsername, username));
    }
    @Override
    public String executeLogin(LoginDTO dto) {
        String token = null;
        try {
            //首先查看客户端传过来的dto的用户名是否存在,调用getUserByUsername 查询
            UmsUser user = getUserByUsername(dto.getUsername());
            //md5 对密码进行加密
            String encodePwd = MD5Utils.getPwd(dto.getPassword());
            //加密后再跟数据库的密码对比一下
            if(!encodePwd.equals(user.getPassword()))
            {
                throw new Exception("密码错误");
            }
            //把用户名作为生成token的种子
            token = JwtUtil.generateToken(String.valueOf(user.getUsername()));
        } catch (Exception e) {
            log.warn("用户不存在or密码验证失败=======>{}", dto.getUsername());
        }
        //返回token 到controller
        return token;
    }


    /**
     *
     * @param id 用户ID
     * @return
     */
    @Override
    public ProfileVO getUserProfile(String id) {
        //初始化ProfileVO对象
        ProfileVO profile = new ProfileVO();
        //从数据库中查找UmsUser对象
        UmsUser user = baseMapper.selectById(id);
        //调用BeanUtils工具类 可以把user对象和profile对象 的相同属性字段的值拷贝,不一样的值就不拷贝
        BeanUtils.copyProperties(user, profile);
        // 用户文章数
        int count = bubbleTopicMapper.selectCount(new LambdaQueryWrapper<BubblePost>().eq(BubblePost::getUserId, id));
        profile.setTopicCount(count);

        // 粉丝数
        int followers = bubbleFollowMapper.selectCount((new LambdaQueryWrapper<BubbleFollow>().eq(BubbleFollow::getParentId, id)));
        profile.setFollowerCount(followers);

        return profile;
    }
}
